/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.editura.oxygen.severin.imageviewer;

import de.editura.common.swing.imageviewer.ImageViewerPanel;
import de.editura.oxygen.severin.imageviewer.features.AutoShowImageAuthorCaretListener;
import de.editura.oxygen.severin.imageviewer.features.ImageViewerPanelController;
import de.editura.oxygen.severin.imageviewer.features.ImagePathAdministration;
import de.editura.oxygen.severin.imageviewer.features.TextEditorCaretListener;
import java.awt.event.ActionEvent;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import ro.sync.ecss.extensions.api.AuthorDocumentController;
import ro.sync.ecss.extensions.api.node.AuthorDocumentFragment;
import ro.sync.exml.editor.EditorPageConstants;
import ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension;
import ro.sync.exml.workspace.api.editor.WSEditor;
import ro.sync.exml.workspace.api.editor.page.author.WSAuthorEditorPage;
import ro.sync.exml.workspace.api.editor.page.text.WSTextEditorPage;
import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace;
import ro.sync.exml.workspace.api.standalone.ToolbarComponentsCustomizer;
import ro.sync.exml.workspace.api.standalone.ToolbarInfo;
import ro.sync.exml.workspace.api.standalone.ViewComponentCustomizer;
import ro.sync.exml.workspace.api.standalone.ViewInfo;
import ro.sync.ui.Icons;

/**
 *
 * @author kschmidtner
 */
public class SeverinImageViewerWorkspaceExtension implements WorkspaceAccessPluginExtension {

    private StandalonePluginWorkspace pluginWorkspaceAccess;
    
    private ImageViewerPanel imageViewerPanel;
    private ImageViewerPanelController ivpc = new ImageViewerPanelController();
    
    private JComboBox imagePathCB;
    private ImagePathAdministration imgPathAdmin;
    JButton activateAutoShowImageButton;
    
    AutoShowImageAuthorCaretListener asiacl;
    TextEditorCaretListener tecl;
    
    
    public void applicationStarted(final StandalonePluginWorkspace pluginWorkspaceAccess) {
        this.pluginWorkspaceAccess = pluginWorkspaceAccess;
        
        //Image-Refresh-Button
        final Action selectionShowImage = new AbstractAction() {

            public void actionPerformed(ActionEvent actionevent) {
                WSEditor editorAccess = 
                        pluginWorkspaceAccess
                        .getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);
                
                ivpc.setImagePathCB(imagePathCB);
                ivpc.setImageViewerPanel(imageViewerPanel);
                ivpc.setPluginWorkspaceAccess(pluginWorkspaceAccess);

                if (editorAccess != null & EditorPageConstants.PAGE_TEXT.equals(editorAccess.getCurrentPageID())) {
                    WSTextEditorPage textEditor = (WSTextEditorPage) editorAccess.getCurrentPage();

                    String selectedText = textEditor.getSelectedText();
                    if (selectedText != null) {
                        ivpc.refreshImageViewer(parseSelection(selectedText));
                        //Todo Debuginfo: pluginWorkspaceAccess.showInformationMessage(selectedText);
                    } else {
                        // No selection
                        pluginWorkspaceAccess.showInformationMessage("No selection available.");
                    }

                }
                // This action is available only in Author mode.
                if (editorAccess != null & EditorPageConstants.PAGE_AUTHOR.equals(editorAccess.getCurrentPageID())) {
                    WSAuthorEditorPage authorPageAccess = (WSAuthorEditorPage) editorAccess.getCurrentPage();
                    AuthorDocumentController controller = authorPageAccess.getDocumentController();
                    if (authorPageAccess.hasSelection()) {
                        AuthorDocumentFragment selectionFragment;
                        try {
                            // Create fragment from selection
                            selectionFragment = controller.createDocumentFragment(
                                    authorPageAccess.getSelectionStart(),
                                    authorPageAccess.getSelectionEnd() - 1);
                            // Serialize
                            String serializeFragmentToXML = controller.serializeFragmentToXML(selectionFragment);
                            // Test pluginWorkspaceAccess.showInformationMessage(serializeFragmentToXML);
                            String derString = parseSelection(serializeFragmentToXML);

                            ivpc.refreshImageViewer(derString);
                        } catch (BadLocationException e) {
                            pluginWorkspaceAccess.showErrorMessage("Show Selection Source operation failed: " + e.getMessage());
                        }
                    } else {
                        // No selection
                        pluginWorkspaceAccess.showInformationMessage("No selection available.");
                    }
                }


            }
        };
        
        
        
        final Action activateAutoShowImage = new AbstractAction() {
            private static final String AUTO__OFF = "Auto Off";
            private static final String AUTO__ON = "Auto On";

            public void actionPerformed(ActionEvent e) {
                WSEditor editorAccess = pluginWorkspaceAccess.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA);

                if (editorAccess != null & EditorPageConstants.PAGE_TEXT.equals(editorAccess.getCurrentPageID())) {
                    WSTextEditorPage textEditor = (WSTextEditorPage) editorAccess.getCurrentPage();
                   
                    JTextArea jtarea = (JTextArea) textEditor.getTextComponent();

                    if (activateAutoShowImageButton.getText().equals(AUTO__OFF)) {
                            ivpc.setImagePathCB(imagePathCB);
                            ivpc.setImageViewerPanel(imageViewerPanel);
                            ivpc.setPluginWorkspaceAccess(pluginWorkspaceAccess);
                            tecl = new TextEditorCaretListener(pluginWorkspaceAccess, ivpc);
                            jtarea.addCaretListener(tecl);
                            activateAutoShowImageButton.setText(AUTO__ON);
                    } else if (activateAutoShowImageButton.getText().equals(AUTO__ON)) {
                            jtarea.removeCaretListener(tecl);
                            activateAutoShowImageButton.setText(AUTO__OFF);
                    }
                }

                if (editorAccess != null & EditorPageConstants.PAGE_AUTHOR.equals(editorAccess.getCurrentPageID())) {

                    WSAuthorEditorPage authorPageAccess = (WSAuthorEditorPage) editorAccess.getCurrentPage();
                    if (activateAutoShowImageButton.getText().equals(AUTO__OFF)) {
                        ivpc.setImagePathCB(imagePathCB);
                        ivpc.setImageViewerPanel(imageViewerPanel);
                        ivpc.setPluginWorkspaceAccess(pluginWorkspaceAccess);
                        asiacl = new AutoShowImageAuthorCaretListener(pluginWorkspaceAccess, ivpc);
                        authorPageAccess.addAuthorCaretListener(asiacl);
                        activateAutoShowImageButton.setText(AUTO__ON);
                    } else if (activateAutoShowImageButton.getText().equals(AUTO__ON)) {
                        authorPageAccess.removeAuthorCaretListener(asiacl);
                        activateAutoShowImageButton.setText(AUTO__OFF);
                    }
                }
            }
        };


        //View-Components
        pluginWorkspaceAccess.addViewComponentCustomizer(new ViewComponentCustomizer() {

            public void customizeView(ViewInfo viewInfo) {
                if (ViewComponentCustomizer.CUSTOM.equals(viewInfo.getViewID())) {
                    //pluginWorkspaceAccess.showInformationMessage(CUSTOM);

                    imageViewerPanel = new ImageViewerPanel();
                    viewInfo.setComponent(new JScrollPane(imageViewerPanel));
                    viewInfo.setTitle("Severin Image Viewer");
                    viewInfo.setIcon(Icons.CMS_MESSAGES_CUSTOM_VIEW);

                }
            }
        });


        pluginWorkspaceAccess.addToolbarComponentsCustomizer(new ToolbarComponentsCustomizer() {

            public void customizeToolbar(ToolbarInfo toolbarInfo) {
                if (ToolbarComponentsCustomizer.CUSTOM.equals(toolbarInfo.getToolbarID())) {
                    // Check In
                    JLabel imagePathLbl = new JLabel();
                    imagePathLbl.setText("Img-Path: ");

                    try {
                        imgPathAdmin = new ImagePathAdministration();
                    } catch (Exception ex) {
                        imgPathAdmin.getLastimgPaths().add(System.getProperty("user.home"));
                    }


                    imgPathAdmin.getLastimgPaths();
                    String[] lastPaths = (String[]) imgPathAdmin.getLastimgPaths().toArray(new String[imgPathAdmin.getLastimgPaths().size()]);

                    // Check Out
                    imagePathCB = new JComboBox(lastPaths);
                    imagePathCB.setSize(10, 30);
                    imagePathCB.setEditable(true);

                    // Show Selection Source
                    JButton selectionSourceButton = new JButton(selectionShowImage);
                    selectionSourceButton.setText("Show Image");

                    activateAutoShowImageButton = new JButton(activateAutoShowImage);
                    activateAutoShowImageButton.setText("Auto Off");

                    // Add in toolbar
                    List<JComponent> comps = new ArrayList<JComponent>();
                    comps.add(imagePathLbl);
                    comps.add(imagePathCB);
                    comps.add(selectionSourceButton);
                    comps.add(activateAutoShowImageButton);
                    toolbarInfo.setComponents(comps.toArray(new JComponent[0]));

                    // Set title
                    toolbarInfo.setTitle("Severin Image Viewer");
                }
            }
        });

    }

    public boolean applicationClosing() {
        //throw new UnsupportedOperationException("Not supported yet.");
        return true;
    }

    //Pluginspezifische Methoden
    
    /* Remark: A selection in author mode contains also XML elements, 
     * not only the visible, selected text.
     */
    public String parseSelection(String selection) {

        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder = null;
        try {

            builder = domFactory.newDocumentBuilder();
            Document doc = builder.parse(new InputSource(new StringReader(selection)));

            selection = simpleInfoParse(doc, "//Vwext/@dateiref");
            //pluginWorkspaceAccess.showInformationMessage("Mit XPath" + selection);
        } catch (ParserConfigurationException ex) {
            //pluginWorkspaceAccess.showInformationMessage(ex.getMessage());
            Logger.getLogger(SeverinImageViewerWorkspaceExtension.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            //pluginWorkspaceAccess.showInformationMessage(ex.getMessage());
            Logger.getLogger(SeverinImageViewerWorkspaceExtension.class.getName()).log(Level.SEVERE, null, ex);
        }


        selection = selection.replaceAll("\\<.*?>", ""); //Entferne alles was von spitzen Klammer eingeschlossen ist
        if (selection.contains("IMG")) {
            selection = selection.replace("IMG", "/IMG");
        }
        if (selection.contains("_MG")) {
            selection = selection.replace("_MG", "/_MG");
        }

        selection = selection.replace("\\", "/");
        selection = selection.trim();
        selection = selection.replaceAll("\\s\\s+|\\n|\\r", ""); //RegEx: Entferne div. Whitespace
        selection = selection.replace("\\t", "");
        return selection;
    }

    private String simpleInfoParse(Document doc, String xPathExpr) {
        String returnStr = "";
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        try {
            XPathExpression expr = xpath.compile(xPathExpr);
            Object result = expr.evaluate(doc, XPathConstants.NODESET);
            NodeList nodes = (NodeList) result;
            for (int i = 0; i < nodes.getLength(); i++) {
                returnStr = nodes.item(i).getNodeValue();
            }
        } catch (XPathExpressionException ex) {
            //pluginWorkspaceAccess.showInformationMessage("in simpleInfoParse ist ein Fehler");
            //Todo Debuginfo: System.out.println("Fehler in simpleInfoParse: " + xPathExpr);
            Logger.getLogger(SeverinImageViewerWorkspaceExtension.class.getName()).log(Level.SEVERE, null, ex);
        }
        return returnStr;
    }

    public ImageViewerPanel getImageViewerPanel() {
        return imageViewerPanel;
    }

    public JComboBox getImagePathCB() {
        return imagePathCB;
    }

    public StandalonePluginWorkspace getPluginWorkspaceAccess() {
        return pluginWorkspaceAccess;
    }

    public ImageViewerPanelController getIvpc() {
        return ivpc;
    }
}
